package ui;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

//import javax.jnlp.FileContents;
//import javax.jnlp.FileOpenService;
import javax.swing.ScrollPaneConstants;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JScrollPane;
import javax.swing.text.BadLocationException;
//import javax.swing.text.html.HTMLDocument;
//import javax.swing.text.html.HTMLEditorKit;

import core.IMessenger;
import core.ISpeaker;
import core.Contact;
import core.ContactList;

public class GUIMessenger extends JFrame implements ActionListener, IMessenger
{
    private JButton         sendButton;
    private JComboBox       receivier;
    private JFileChooser    fc;
    private JMenuItem       addContactMenuItem;
    private JMenuItem       sendFileMenuItem;
    private JTextArea       message;
    private JTextPane       received;
    private String[]          history;
    private JScrollPane     recievedScroll;
    private JScrollPane     messageScroll;
   	
	protected ISpeaker speaker;
    
    private void send()
    {
        String msg = "";
        String text = message.getText();
        int totalLines = message.getLineCount();
        for (int i=0; i < totalLines; i++) {
            try {
                int start = message.getLineStartOffset(i);
                int end   = message.getLineEndOffset(i);
                String line = text.substring(start, end);
              // line.append(System.getProperty("line.separator"));
                msg += line + "\n";
                
            }
            catch( BadLocationException ex) {
            }
         }

        if (!msg.isEmpty()) {
            Contact contact = ContactList.instance().get(receivier.getSelectedIndex());
            int cur = getContactInd(contact);
            updateHistory(cur, "Me", msg);
            printHistory(cur);
            speaker.sendMessage(contact, msg);
        }
        message.setText("");
    }
    
    private void sendFile()
    {
        int r = fc.showOpenDialog(this);
        if (r == JFileChooser.APPROVE_OPTION)
        {
            File f = fc.getSelectedFile();
            if (f.exists() && f.isFile())
            {
                try
                {
                    String name = f.getName();
                    FileInputStream in = new FileInputStream(f);
                    byte[] data = null;
                    String body;
                    if (in.available() > 0)
                    {
                        data = new byte[in.available()];
                        in.read(data);
                    }
                    speaker.sendFile(ContactList.instance().get(receivier.getSelectedIndex()), name, data);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
    
    private void addContact()
    {
        int port = Integer.parseInt((String)JOptionPane.showInputDialog(
                    this,
                    "Port",
                    "Add contact",
                    JOptionPane.PLAIN_MESSAGE,
                    null,
                    null,
                    "1000"));
        String host = (String)JOptionPane.showInputDialog(
                    this,
                    "Host",
                    "Add contact",
                    JOptionPane.PLAIN_MESSAGE,
                    null,
                    null,
                    "127.0.0.1");
        ContactList.instance().add(host, port);
        updateContacts();
    }
    
    private void updateContacts()
    {
        receivier.removeAllItems();
        int count = ContactList.instance().getCount();
        for (int i = 0; i < count; i++)
            receivier.addItem(ContactList.instance().get(i));
    }
    
    private int getContactInd (Contact contact)
    {
        int count = ContactList.instance().getCount();
        for (int i = 0; i < count; i++)
            if (contact == ContactList.instance().get(i))
                return i;
        return -1;
    }
    
    public void actionPerformed(ActionEvent e)
    {
        if (e.getSource() == sendButton)
        {
            send();
        }
        else if (e.getSource() == addContactMenuItem)
        {
            addContact();
        }
        else if (e.getSource() == sendFileMenuItem)
        {
            sendFile();
        }
        
    }
    public void printHistory(int ind)
    {
        received.setText("");
        if (history[ind] != null) {
             String[] str = history[ind].split("\n");
             for (int i = 0; i < str.length; i++)
                 if (!str[i].equals("") )
                     try {
                          received.getStyledDocument().insertString(received.getStyledDocument().getLength(), 
                         str[i] + "\n", null);
                     }
                    catch (BadLocationException ex) {
                    }
        }
       
    }
    
    private void updateHistory (int cur, String author, String message)
    {
        if (history[cur]== null ) {
                  history[cur] = new String();
                  history[cur] = "";
            }
        history[cur] = history[cur] + String.format("%s:\n%s\n", author, message);
            
    }
    
    public GUIMessenger(ISpeaker s)
    {
        int max_contact_num = 1000;
	speaker = s;
	speaker.setMessenger(this);
        
        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
        JPanel pane = new JPanel();
        pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS));
        pane.setPreferredSize(new Dimension(100, 100));
        pane.setMinimumSize(new Dimension(100, 100));
        add(pane);
        
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("Actions");
        menuBar.add(menu);
        menu.setMaximumSize(new Dimension((int)(50), 30));
        menu.setPreferredSize(new Dimension((int)(50), 30));
        menu.setMinimumSize(new Dimension((int)(50), 30));
        menu.setAlignmentX(CENTER_ALIGNMENT);
        menu.setAlignmentY(CENTER_ALIGNMENT);
        
        addContactMenuItem = new JMenuItem("Add contact...");
        addContactMenuItem.addActionListener(this);
        menu.add(addContactMenuItem);
        sendFileMenuItem = new JMenuItem("Send file");
        sendFileMenuItem.addActionListener(this);
        menu.add(sendFileMenuItem);      
        add(menuBar);
	
        pane.add(new JLabel("To:"));
       
        receivier = new JComboBox();
        updateContacts();       
        int hi = (int) ( pane.getPreferredSize().getHeight() * 0.2) / 1;
        receivier.setMaximumSize(new Dimension((int)(Integer.MAX_VALUE), hi));
        receivier.setPreferredSize(new Dimension( (int)(pane.getPreferredSize().getWidth() / 1), hi));  
        receivier.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(ItemEvent event) {
                if (event.getStateChange() == ItemEvent.SELECTED) {
                    int cur;
                    try {
                        cur = receivier.getSelectedIndex();
                        if (cur < 0 || cur >= receivier.getItemCount())
                            cur = 0;
                    }
                    catch (Exception ex) {
                        cur = 0;
                    }
                    printHistory(cur);
                }
            }
        });
        pane.add(receivier);
        add(pane);
        
        received = new JTextPane();
        received.setContentType("text/html");
        received.setBorder(new javax.swing.border.LineBorder(java.awt.Color.BLACK,1));        
        add(received);
        
        recievedScroll = new JScrollPane(received);
        recievedScroll.setVerticalScrollBarPolicy( javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        add(recievedScroll);
        
        history = new String [max_contact_num];
        for (int i = 0; i < max_contact_num; i++)
            history[i] = null;

        pane = new JPanel();
        pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS));
        message = new JTextArea();
        message.setBorder(new javax.swing.border.LineBorder(java.awt.Color.BLACK,1));
        pane.add(message);
       
        messageScroll = new JScrollPane(message);
        messageScroll.setVerticalScrollBarPolicy( javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        add(messageScroll);
        
        sendButton = new JButton("Send");
        sendButton.addActionListener(this);
        pane.add(sendButton);
        add(pane);
        
        fc = new JFileChooser();
    }
    
    public void messageReceived(Contact contact, String message)
    {
        // update contact list if neccessary
        if (!ContactList.instance().contains(contact))
        {
            System.out.println("add contact");
            ContactList.instance().add(contact); //TODO: request to user
        }
        updateContacts();
        
        // determine history
        int cur = getContactInd (contact);
        if (cur >= 0) {            
            updateHistory(cur, contact.toString(), message);
            /*
            if (history[cur]== null ) {
                  history[cur] = new String();
                  history[cur] = "";
            }
            history[cur] = history[cur] + String.format("%s:\n%s\n", contact.toString(), message);
            */
            int selectedInd;
            try {
                selectedInd = receivier.getSelectedIndex();
                if (selectedInd == cur) {
                    System.out.printf(history[cur]);
                    printHistory(cur);
                }
            }
            catch (Exception ex) {
            }
           
        }
    }

    public void fileReceived(Contact contact, String name, byte[] body)
    {
        int r = JOptionPane.showConfirmDialog(this,
                                            String.format("Incoming file \"%s\" from contact %s. Accept?", name, contact.toString()),
                                            "Incoming file",
                                            JOptionPane.YES_NO_OPTION);
        if (r == JOptionPane.YES_OPTION)
        {
            try
            {
                File dir = new File("./received/");
                if (!dir.exists())
                {
                    dir.mkdirs();
                }
                r = fc.showSaveDialog(this);
                if (r == JFileChooser.APPROVE_OPTION)
                {
                    //File f = new File("./received/"+name);
                    File f = fc.getSelectedFile();
                    if (!f.exists())
                    {
                        f.createNewFile();
                    }
                    FileOutputStream out = new FileOutputStream(f);
                    out.write(body);
                    out.flush();
                   // history = history + String.format("<b>received file %s from contact %s</b>\n", f.getName(), contact.toString());
                   // received.setText(history);
                }
                updateContacts();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}